package com.farsunset.cim.nio.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class MD5FileUtil {


	protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	protected static MessageDigest messagedigest = null;

	static {
		try {
			// 初始化MD5
			messagedigest = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
		}
	}

	/**
	 * 获取文件的 MD5
	 * 
	 * @param file
	 *            文件
	 * @return MD5 值
	 * @throws IOException
	 */
	public synchronized static String getFileMD5String(File file)
			throws IOException {
		FileInputStream in = new FileInputStream(file);
		// FileChannel 用于读取、写入、映射和操作文件的通道
		FileChannel ch = in.getChannel();
		/*
		 * ch.map 将此通道的文件区域直接映射到内存中 map(FileChannel.MapMode mode,long
		 * position,long size) mode:只读、读写、专用 position：开始位置 size:要映射的区域大小
		 */
		MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
				file.length());
		// 更新MD5
		messagedigest.update(byteBuffer);
		// 更新并且计算MD5 将byte转换成String
		return bufferToHex(messagedigest.digest());
	}

	/**
	 * 将byte转换为String
	 * @Title: bufferToHex 
	 * @throws
	 */
	private static String bufferToHex(byte bytes[]) {
		return bufferToHex(bytes, 0, bytes.length);
	}

	private static String bufferToHex(byte bytes[], int m, int n) {
		StringBuffer stringbuffer = new StringBuffer(2 * n);
		int k = m + n;
		for (int l = m; l < k; l++) {
			appendHexPair(bytes[l], stringbuffer);
		}
		return stringbuffer.toString();
	}

	private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
		char c0 = hexDigits[(bt & 0xf0) >> 4];
		char c1 = hexDigits[bt & 0xf];
		stringbuffer.append(c0);
		stringbuffer.append(c1);
	}

	public static void main(String[] args) throws IOException {
		long begin = System.currentTimeMillis();

		File big = new File("E:/temp/netty2/d73f7440d82ba782b86b98a443254e64.jpg");
		String md5 = getFileMD5String(big);
		
		File big2 = new File("E:/temp/netty2/0002.jpg");
		String md52 = getFileMD5String(big2);
		System.out.println("md5:"+md5);
		System.out.println("md52:"+md52);

		long end = System.currentTimeMillis();
		System.out.println("md5:" + md5);
		System.out.println("time:" + ((end - begin)));

	}

}